package com.base.andlanggl.filter

import android.opengl.GLES20.*
import android.opengl.Matrix
import com.base.andlangcore.util.LogUtils
import com.base.andlanggl.util.LangGLTools
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import kotlin.math.max
import kotlin.math.min

class QgqGame2 {
    /**
     * attribute 把属性放进着色器的手段
     * uniform 把属性放进着色器的手段 mat4 4*4矩阵
     * vec4 4个分量坐标 xyzw 默认值分别0001
     * varying 混合颜色 将顶点颜色进行混合
     * gl_PointSize 点的大小
     */
    private val vertexShader:String ="""
        uniform mat4 u_Matrix;
        attribute vec4 a_Position;
        attribute vec4 a_Color;
        varying vec4 v_Color;
        void main(){
            v_Color=a_Color;
            gl_Position= u_Matrix*a_Position;
            gl_PointSize= 10.0;
        }"""

    /**
     *  浮点型精度 mediump ，默认高精度
     *  varying 4个分量rgba 接收顶点着色器传过来的数据
     */
    private val fragmentShader:String ="""
        precision mediump float;
        varying vec4 v_Color;
        void main(){
            gl_FragColor= v_Color;
        }"""

    private val BYTES_PER_FLOAT=4 //字节倍数
    private val POSITION_COMPONENT_COUNT=2 //为顶点坐标传入2个分量 但是一个顶点有4个分量其它值默认xyz w特殊
    private val COLOR_COMPONENT_COUNT=3 //为每个顶点色值传入3个分量 rgba 最后一个a分量会默认1
    private lateinit var vertexData: FloatBuffer //GPU创建顶点数据空间
    //重要 步长单位是字节
    private val STRIDE=(POSITION_COMPONENT_COUNT+COLOR_COMPONENT_COUNT)*BYTES_PER_FLOAT
    //顶点坐标 一个三角形扇组成的4个三角形 一条线 两个点 每个顶点后面带rgb颜色数据
    private var tableVerticesWithTriangles:FloatArray= floatArrayOf(
        0.0f,0.0f,1f,1f,1f,
        -0.5f,-0.8f,0.7f,0.7f,0.7f,
        0.5f,-0.8f,0.7f,0.7f,0.7f,
        0.5f,0.8f,0.7f,0.7f,0.7f,
        -0.5f,0.8f,0.7f,0.7f,0.7f,
        -0.5f,-0.8f,0.7f,0.7f,0.7f,

        -0.5f,0f,1.0f,0.0f,0.0f,
        0.5f,0f,1.0f,0.0f,0.0f,

        0f,0.25f,0.0f,0.0f,1.0f,
        0f,-0.25f,1.0f,0.0f,0.0f
    )
    //矩阵数据 4*4矩阵
    private var projectionMatrix:FloatArray=FloatArray(16)

    //链接程序id
    private var glProgram=0
    //程序中的参数 获取属性位置
    private var aPositionLocation=0
    //程序中的参数 获取颜色位置
    private var aColorLocation=0
    //矩阵参数id
    private var uMatrixLocation=0

    //初始化
    fun initGame(){
        //设置清空屏幕的色值 红 绿 蓝 alpha
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
        //创建空间浮点个数*字节倍数
        //一个浮点型32位 opengl中一个字节8位 字节倍数BYTES_PER_FLOAT=4
        vertexData= ByteBuffer.allocateDirect(tableVerticesWithTriangles.size* BYTES_PER_FLOAT)
            .order(ByteOrder.nativeOrder()).asFloatBuffer()
        //放入数据
        vertexData.put(tableVerticesWithTriangles)

        //创建顶点着色器和片段着色器链接程序
        glProgram= LangGLTools.createProgram(vertexShader,fragmentShader)
        glUseProgram(glProgram)//使用程序
        aPositionLocation= glGetAttribLocation(glProgram, "a_Position")//获取属性位置
        aColorLocation= glGetAttribLocation(glProgram, "a_Color")//获取颜色位置
        uMatrixLocation=glGetUniformLocation(glProgram,"u_Matrix")//获取矩阵位置

        //顶点坐标数据 将数据指向开始位置 从0开始的
        vertexData.position(0)
        //将顶点数据和属性位置关联 属性位置,顶点坐标分量个数是2 这里是xy两个,数据类型,false整型才有意义,步长,数据
        glVertexAttribPointer(
            aPositionLocation,
            POSITION_COMPONENT_COUNT,
            GL_FLOAT,
            false,
            STRIDE, //重要 步长单位是字节
            vertexData
        )
        //颜色数据 将数据跳过第一个顶点坐标数据 从下标2开始的
        vertexData.position(POSITION_COMPONENT_COUNT)
        //将颜色数据和颜色位置关联,顶点坐标分量个数是3 这里是rgb三个,数据类型,false整型才有意义,步长,数据
        glVertexAttribPointer(
            aColorLocation,
            COLOR_COMPONENT_COUNT,
            GL_FLOAT,
            false,
            STRIDE, //重要 步长单位是字节
            vertexData
        )

        glEnableVertexAttribArray(aPositionLocation)//使用顶点坐标数据
        glEnableVertexAttribArray(aColorLocation)//使用颜色数据
    }

    fun drawViewport(width: Int, height: Int){
        //画布宽高左上角 右下角 坐标
        glViewport(0, 0, width, height)
        //使用正交矩阵
        var aspectRatio:Float= max(width,height)*1.0f / min(width,height)
        if (width>height){
            Matrix.orthoM(projectionMatrix,0,-aspectRatio,aspectRatio,-1f,1f,-1f,1f)
        }else{
            Matrix.orthoM(projectionMatrix,0,-1f,1f,-aspectRatio,aspectRatio,-1f,1f)
        }
        LogUtils.d(projectionMatrix.contentToString())
    }

    //绘制
    fun drawGame(){
        //清空屏幕
        glClear(GL_COLOR_BUFFER_BIT)
        //传入矩阵数据
        glUniformMatrix4fv(uMatrixLocation,1,false,projectionMatrix,0)

        //开始绘制
        glDrawArrays(GL_TRIANGLE_FAN, 0, 6) //绘制一个三角形扇 从顶点坐标下标第0个数据开始读取 读取6个顶点
        glDrawArrays(GL_LINES, 6, 2) //绘制线 从顶点坐标下标第6个开始读取 读取2个顶点
        glDrawArrays(GL_POINTS, 8, 1) //绘制点 从顶点坐标下标第8个开始读取 读取1个顶点
        glDrawArrays(GL_POINTS, 9, 1) //绘制点 从顶点坐标下标第9个开始读取 读取1个顶点
    }
}